home *** CD-ROM | disk | FTP | other *** search
/ CD/PC Actual 31 / PC Actual CD 31.iso / dists / SRC / SLIBEXEC.AA / SLIBEXEC / libexec / bootpd / dumptab.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-29  |  8.9 KB  |  385 lines

  1. /*
  2.  * dumptab.c - handles dumping the database
  3.  *
  4.  *    $Id: dumptab.c,v 1.5 1998/06/29 16:47:08 bde Exp $
  5.  */
  6.  
  7. #include <sys/types.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>            /* inet_ntoa */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <syslog.h>
  14. #include <time.h>
  15.  
  16. #ifndef USE_BFUNCS
  17. #include <memory.h>
  18. /* Yes, memcpy is OK here (no overlapped copies). */
  19. #define bcopy(a,b,c)    memcpy(b,a,c)
  20. #define bzero(p,l)      memset(p,0,l)
  21. #define bcmp(a,b,c)     memcmp(a,b,c)
  22. #endif
  23.  
  24. #include "bootp.h"
  25. #include "hash.h"
  26. #include "hwaddr.h"
  27. #include "report.h"
  28. #include "patchlevel.h"
  29. #include "bootpd.h"
  30.  
  31. #ifdef    __STDC__
  32. #define P(args) args
  33. #else
  34. #define P(args) ()
  35. #endif
  36.  
  37. static void dump_generic P((FILE *, struct shared_bindata *));
  38. static void dump_host P((FILE *, struct host *));
  39. static void list_ipaddresses P((FILE *, struct in_addr_list *));
  40.  
  41. #undef P
  42.  
  43. #ifndef    DEBUG
  44. void
  45. dumptab(filename)
  46.     char *filename;
  47. {
  48.     report(LOG_INFO, "No dumptab support!");
  49. }
  50.  
  51. #else /* DEBUG */
  52.  
  53. /*
  54.  * Dump the internal memory database to bootpd_dump.
  55.  */
  56.  
  57. void
  58. dumptab(filename)
  59.     char *filename;
  60. {
  61.     int n;
  62.     struct host *hp;
  63.     FILE *fp;
  64.     time_t t;
  65.     /* Print symbols in alphabetical order for reader's convenience. */
  66.     static char legend[] = "#\n# Legend:\t(see bootptab.5)\n\
  67. #\tfirst field -- hostname (not indented)\n\
  68. #\tbf -- bootfile\n\
  69. #\tbs -- bootfile size in 512-octet blocks\n\
  70. #\tcs -- cookie servers\n\
  71. #\tdf -- dump file name\n\
  72. #\tdn -- domain name\n\
  73. #\tds -- domain name servers\n\
  74. #\tef -- extension file\n\
  75. #\tex -- exec file (YORK_EX_OPTION)\n\
  76. #\tgw -- gateways\n\
  77. #\tha -- hardware address\n\
  78. #\thd -- home directory for bootfiles\n\
  79. #\thn -- host name set for client\n\
  80. #\tht -- hardware type\n\
  81. #\tim -- impress servers\n\
  82. #\tip -- host IP address\n\
  83. #\tlg -- log servers\n\
  84. #\tlp -- LPR servers\n\
  85. #\tms -- message size\n\
  86. #\tmw -- min wait (secs)\n\
  87. #\tns -- IEN-116 name servers\n\
  88. #\tnt -- NTP servers (RFC 1129)\n\
  89. #\tra -- reply address override\n\
  90. #\trl -- resource location protocol servers\n\
  91. #\trp -- root path\n\
  92. #\tsa -- boot server address\n\
  93. #\tsm -- subnet mask\n\
  94. #\tsw -- swap server\n\
  95. #\ttc -- template host (points to similar host entry)\n\
  96. #\ttd -- TFTP directory\n\
  97. #\tto -- time offset (seconds)\n\
  98. #\tts -- time servers\n\
  99. #\tvm -- vendor magic number\n\
  100. #\tyd -- YP (NIS) domain\n\
  101. #\tys -- YP (NIS) servers\n\
  102. #\tTn -- generic option tag n\n\
  103. \n";
  104.  
  105.     /*
  106.      * Open bootpd.dump file.
  107.      */
  108.     if ((fp = fopen(filename, "w")) == NULL) {
  109.         report(LOG_ERR, "error opening \"%s\": %s",
  110.                filename, get_errmsg());
  111.         exit(1);
  112.     }
  113.     t = time(NULL);
  114.     fprintf(fp, "\n# %s %s.%d\n", progname, VERSION, PATCHLEVEL);
  115.     fprintf(fp, "# %s: dump of bootp server database.\n", filename);
  116.     fprintf(fp, "# Dump taken %s", ctime(&t));
  117.     fwrite(legend, 1, sizeof(legend) - 1, fp);
  118.  
  119.     n = 0;
  120.     for (hp = (struct host *) hash_FirstEntry(nmhashtable); hp != NULL;
  121.          hp = (struct host *) hash_NextEntry(nmhashtable)) {
  122.         dump_host(fp, hp);
  123.         fprintf(fp, "\n");
  124.         n++;
  125.     }
  126.     fclose(fp);
  127.  
  128.     report(LOG_INFO, "dumped %d entries to \"%s\".", n, filename);
  129. }
  130.  
  131.  
  132.  
  133. /*
  134.  * Dump all the available information on the host pointed to by "hp".
  135.  * The output is sent to the file pointed to by "fp".
  136.  */
  137.  
  138. static void
  139. dump_host(fp, hp)
  140.     FILE *fp;
  141.     struct host *hp;
  142. {
  143.     /* Print symbols in alphabetical order for reader's convenience. */
  144.     if (hp) {
  145.         fprintf(fp, "%s:", (hp->hostname ?
  146.                             hp->hostname->string : "?"));
  147.         if (hp->flags.bootfile) {
  148.             fprintf(fp, "\\\n\t:bf=%s:", hp->bootfile->string);
  149.         }
  150.         if (hp->flags.bootsize) {
  151.             fprintf(fp, "\\\n\t:bs=");
  152.             if (hp->flags.bootsize_auto) {
  153.                 fprintf(fp, "auto:");
  154.             } else {
  155.                 fprintf(fp, "%lu:", (u_long)hp->bootsize);
  156.             }
  157.         }
  158.         if (hp->flags.cookie_server) {
  159.             fprintf(fp, "\\\n\t:cs=");
  160.             list_ipaddresses(fp, hp->cookie_server);
  161.             fprintf(fp, ":");
  162.         }
  163.         if (hp->flags.dump_file) {
  164.             fprintf(fp, "\\\n\t:df=%s:", hp->dump_file->string);
  165.         }
  166.         if (hp->flags.domain_name) {
  167.             fprintf(fp, "\\\n\t:dn=%s:", hp->domain_name->string);
  168.         }
  169.         if (hp->flags.domain_server) {
  170.             fprintf(fp, "\\\n\t:ds=");
  171.             list_ipaddresses(fp, hp->domain_server);
  172.             fprintf(fp, ":");
  173.         }
  174.         if (hp->flags.exten_file) {
  175.             fprintf(fp, "\\\n\t:ef=%s:", hp->exten_file->string);
  176.         }
  177.         if (hp->flags.exec_file) {
  178.             fprintf(fp, "\\\n\t:ex=%s:", hp->exec_file->string);
  179.         }
  180.         if (hp->flags.gateway) {
  181.             fprintf(fp, "\\\n\t:gw=");
  182.             list_ipaddresses(fp, hp->gateway);
  183.             fprintf(fp, ":");
  184.         }
  185.         /* FdC: swap_server (see below) */
  186.         if (hp->flags.homedir) {
  187.             fprintf(fp, "\\\n\t:hd=%s:", hp->homedir->string);
  188.         }
  189.         /* FdC: dump_file (see above) */
  190.         /* FdC: domain_name (see above) */
  191.         /* FdC: root_path (see below) */
  192.         if (hp->flags.name_switch && hp->flags.send_name) {
  193.             fprintf(fp, "\\\n\t:hn:");
  194.         }
  195.         if (hp->flags.htype) {
  196.             int hlen = haddrlength(hp->htype);
  197.             fprintf(fp, "\\\n\t:ht=%u:", (unsigned) hp->htype);
  198.             if (hp->flags.haddr) {
  199.                 fprintf(fp, "ha=\"%s\":",
  200.                         haddrtoa(hp->haddr, hlen));
  201.             }
  202.         }
  203.         if (hp->flags.impress_server) {
  204.             fprintf(fp, "\\\n\t:im=");
  205.             list_ipaddresses(fp, hp->impress_server);
  206.             fprintf(fp, ":");
  207.         }
  208.         /* NetBSD: swap_server (see below) */
  209.         if (hp->flags.iaddr) {
  210.             fprintf(fp, "\\\n\t:ip=%s:", inet_ntoa(hp->iaddr));
  211.         }
  212.         if (hp->flags.log_server) {
  213.             fprintf(fp, "\\\n\t:lg=");
  214.             list_ipaddresses(fp, hp->log_server);
  215.             fprintf(fp, ":");
  216.         }
  217.         if (hp->flags.lpr_server) {
  218.             fprintf(fp, "\\\n\t:lp=");
  219.             list_ipaddresses(fp, hp->lpr_server);
  220.             fprintf(fp, ":");
  221.         }
  222.         if (hp->flags.msg_size) {
  223.             fprintf(fp, "\\\n\t:ms=%lu:", (u_long)hp->msg_size);
  224.         }
  225.         if (hp->flags.min_wait) {
  226.             fprintf(fp, "\\\n\t:mw=%lu:", (u_long)hp->min_wait);
  227.         }
  228.         if (hp->flags.name_server) {
  229.             fprintf(fp, "\\\n\t:ns=");
  230.             list_ipaddresses(fp, hp->name_server);
  231.             fprintf(fp, ":");
  232.         }
  233.         if (hp->flags.ntp_server) {
  234.             fprintf(fp, "\\\n\t:nt=");
  235.             list_ipaddresses(fp, hp->ntp_server);
  236.             fprintf(fp, ":");
  237.         }
  238.         if (hp->flags.reply_addr) {
  239.             fprintf(fp, "\\\n\t:ra=%s:", inet_ntoa(hp->reply_addr));
  240.         }
  241.         if (hp->flags.rlp_server) {
  242.             fprintf(fp, "\\\n\t:rl=");
  243.             list_ipaddresses(fp, hp->rlp_server);
  244.             fprintf(fp, ":");
  245.         }
  246.         if (hp->flags.root_path) {
  247.             fprintf(fp, "\\\n\t:rp=%s:", hp->root_path->string);
  248.         }
  249.         if (hp->flags.bootserver) {
  250.             fprintf(fp, "\\\n\t:sa=%s:", inet_ntoa(hp->bootserver));
  251.         }
  252.         if (hp->flags.subnet_mask) {
  253.             fprintf(fp, "\\\n\t:sm=%s:", inet_ntoa(hp->subnet_mask));
  254.         }
  255.         if (hp->flags.swap_server) {
  256.             fprintf(fp, "\\\n\t:sw=%s:", inet_ntoa(hp->subnet_mask));
  257.         }
  258.         if (hp->flags.tftpdir) {
  259.             fprintf(fp, "\\\n\t:td=%s:", hp->tftpdir->string);
  260.         }
  261.         /* NetBSD: rootpath (see above) */
  262.         /* NetBSD: domainname (see above) */
  263.         /* NetBSD: dumpfile (see above) */
  264.         if (hp->flags.time_offset) {
  265.             fprintf(fp, "\\\n\t:to=%ld:", hp->time_offset);
  266.         }
  267.         if (hp->flags.time_server) {
  268.             fprintf(fp, "\\\n\t:ts=");
  269.             list_ipaddresses(fp, hp->time_server);
  270.             fprintf(fp, ":");
  271.         }
  272.         if (hp->flags.vm_cookie) {
  273.             fprintf(fp, "\\\n\t:vm=");
  274.             if (!bcmp(hp->vm_cookie, vm_rfc1048, 4)) {
  275.                 fprintf(fp, "rfc1048:");
  276.             } else if (!bcmp(hp->vm_cookie, vm_cmu, 4)) {
  277.                 fprintf(fp, "cmu:");
  278.             } else {
  279.                 fprintf(fp, "%d.%d.%d.%d:",
  280.                         (int) ((hp->vm_cookie)[0]),
  281.                         (int) ((hp->vm_cookie)[1]),
  282.                         (int) ((hp->vm_cookie)[2]),
  283.                         (int) ((hp->vm_cookie)[3]));
  284.             }
  285.         }
  286.         if (hp->flags.nis_domain) {
  287.             fprintf(fp, "\\\n\t:yd=%s:",
  288.                     hp->nis_domain->string);
  289.         }
  290.         if (hp->flags.nis_server) {
  291.             fprintf(fp, "\\\n\t:ys=");
  292.             list_ipaddresses(fp, hp->nis_server);
  293.             fprintf(fp, ":");
  294.         }
  295.         /*
  296.          * XXX - Add new tags here (or above,
  297.          * so they print in alphabetical order).
  298.          */
  299.  
  300.         if (hp->flags.generic) {
  301.             dump_generic(fp, hp->generic);
  302.         }
  303.     }
  304. }
  305.  
  306.  
  307. static void
  308. dump_generic(fp, generic)
  309.     FILE *fp;
  310.     struct shared_bindata *generic;
  311. {
  312.     u_char *bp = generic->data;
  313.     u_char *ep = bp + generic->length;
  314.     u_char tag;
  315.     int len;
  316.  
  317.     while (bp < ep) {
  318.         tag = *bp++;
  319.         if (tag == TAG_PAD)
  320.             continue;
  321.         if (tag == TAG_END)
  322.             return;
  323.         len = *bp++;
  324.         if (bp + len > ep) {
  325.             fprintf(fp, " #junk in generic! :");
  326.             return;
  327.         }
  328.         fprintf(fp, "\\\n\t:T%d=", tag);
  329.         while (len) {
  330.             fprintf(fp, "%02X", *bp);
  331.             bp++;
  332.             len--;
  333.             if (len)
  334.                 fprintf(fp, ".");
  335.         }
  336.         fprintf(fp, ":");
  337.     }
  338. }
  339.  
  340.  
  341.  
  342. /*
  343.  * Dump an entire struct in_addr_list of IP addresses to the indicated file.
  344.  *
  345.  * The addresses are printed in standard ASCII "dot" notation and separated
  346.  * from one another by a single space.  A single leading space is also
  347.  * printed before the first adddress.
  348.  *
  349.  * Null lists produce no output (and no error).
  350.  */
  351.  
  352. static void
  353. list_ipaddresses(fp, ipptr)
  354.     FILE *fp;
  355.     struct in_addr_list *ipptr;
  356. {
  357.     unsigned count;
  358.     struct in_addr *addrptr;
  359.  
  360.     if (ipptr) {
  361.         count = ipptr->addrcount;
  362.         addrptr = ipptr->addr;
  363.         while (count > 0) {
  364.             fprintf(fp, "%s", inet_ntoa(*addrptr++));
  365.             count--;
  366.             if (count)
  367.                 fprintf(fp, ", ");
  368.         }
  369.     }
  370. }
  371.  
  372. #endif /* DEBUG */
  373.  
  374. /*
  375.  * Local Variables:
  376.  * tab-width: 4
  377.  * c-indent-level: 4
  378.  * c-argdecl-indent: 4
  379.  * c-continued-statement-offset: 4
  380.  * c-continued-brace-offset: -4
  381.  * c-label-offset: -4
  382.  * c-brace-offset: 0
  383.  * End:
  384.  */
  385.